﻿using System.Threading;

namespace HaoCoding.DCdb.General.Threading
{
    /// <summary>
    /// 计数器
    /// </summary>
    public class Countdown
    {
        /// <summary>
        /// 原子计数器
        /// </summary>
        private long count;

        /// <summary>
        /// 原子级加1
        /// </summary>
        public void Increment()
        {
            Interlocked.Increment(ref count); // Interlocked.Increment多线程互锁函数，用在同一进程内，需要对共享的变量做加法的时候，防止其他线程访问这个变量
        }

        /// <summary>
        /// 原子级减1
        /// </summary>
        public void Decrement()
        {
            Interlocked.Decrement(ref count); // Interlocked.Decrement多线程互锁函数，用在同一进程内，需要对共享的变量做减法的时候，防止其他线程访问这个变量
        }

        /// <summary>
        /// 等待并根据原子计数器来判断是否休眠1ms
        /// </summary>
        public void Wait()
        {
            SpinWait wait = new SpinWait();  // SpinWait的性能高于Thread.Sleep。Thread.Slepp就算设置0ms，都会有停和起的动作，故会导致性能偏低

            wait.SpinOnce();  // 执行一次自旋。当SpinWait自旋达到一定次数后，如果有必要当前线程会让出底层的时间片并触发上下文切换。

            while (Count > 0)
                Thread.Sleep(1);
        }

        /// <summary>
        /// 获取原子long值
        /// </summary>
        public long Count
        {
            get { return Interlocked.Read(ref count); }  //Interlocked.Read返回一个以原子操作形式加载的long值
        }
    }
}
